package cn.mw.cmdb.config;

import cn.hutool.core.bean.BeanDesc;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.PropDesc;
import cn.mw.components.mongodb.anno.AutoId;
import cn.mw.microMonitorCommon.util.IDModelType;
import cn.mw.microMonitorCommon.util.ModuleIDManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;

@Slf4j
public class MongodbAutoIdEventListener extends AbstractMongoEventListener<Object> {

    public ModuleIDManager moduleIDManager;

    public MongodbAutoIdEventListener(ModuleIDManager moduleIDManager){
        this.moduleIDManager = moduleIDManager;
    }

    @Override
    public void onBeforeConvert(BeforeConvertEvent<Object> event) {

        Object source = event.getSource();
        BeanDesc desc = BeanUtil.getBeanDesc(source.getClass());
        Iterator<PropDesc> ite = desc.getProps().iterator();
        while (ite.hasNext()) {
            PropDesc propDesc = ite.next();
            Field field = propDesc.getField();
            Annotation annotation = field.getAnnotation(AutoId.class);
            if(null != annotation) {
                Method getMethod = desc.getGetter(propDesc.getFieldName());
                Object obj = null;
                try {
                    obj  = getMethod.invoke(source,null);
                    //如果id值为null,则自动生成id
                    if(null == obj){
                        Method setMethod = desc.getSetter(propDesc.getFieldName());
                        if(field.getType().isAssignableFrom(String.class)){
                            setMethod.invoke(source,moduleIDManager.getIDStr(IDModelType.Model));
                        }else{
                            setMethod.invoke(source,moduleIDManager.getID(IDModelType.Model));
                        }
                    }
                }catch (Exception e){
                    log.error("onBeforeConvert {}" ,e);
                }
            }
        }

        super.onBeforeConvert(event);
    }
}
